#include "bmiManager.h"
#include <common/settings.h>
#include <common/constants.h>

#include <QFile>
#include <QMessageBox>
#include <QDebug>

using namespace Constants;

BmiManager::BmiManager(QObject * parent)
{
    Q_UNUSED(parent);
    m_weight_female_model = new QStandardItemModel(0,SD_MaxParam);
    m_height_female_model = new QStandardItemModel(0,SD_MaxParam);
    m_bmi_female_model = new QStandardItemModel(0,SD_MaxParam);
    m_weight_male_model = new QStandardItemModel(0,SD_MaxParam);
    m_height_male_model = new QStandardItemModel(0,SD_MaxParam);
    m_bmi_male_model = new QStandardItemModel(0,SD_MaxParam);
    settings set;
    m_pathToCsvFiles = set.csvdatasfilePath()+"/";
    getAllModelsEntireLife();
    setAllLifeBmiAccordMonths();
}

BmiManager::~BmiManager(){}

QStandardItemModel * BmiManager::getDatasFromCsvFiles(const QString & csvFile)
{
    QStandardItemModel * model = new QStandardItemModel(0,SD_MaxParam);
    QFile file(m_pathToCsvFiles+csvFile);
    if (!file.open(QIODevice::ReadOnly))
    {
    	  qWarning() << __FILE__ << QString::number(__LINE__) << "UNABLE to open file "+csvFile ;
        }
    QTextStream stream(&file);
    while (!stream.atEnd())
    {
    	QString line = stream.readLine();
    	QStringList list = line.split(",");
    	QList<QStandardItem *> listOfItems;
    	if (!list[SD_SEX].isEmpty())
            {
            for (int i = 0; i < list.count(); ++i)
            {
                QStandardItem * item = new QStandardItem(list[i]);
                listOfItems << item;
                }        	  
            }//for
         model->appendRow(listOfItems);
        }//while
    return model;
}

void  BmiManager::getAllModelsEntireLife()
{
    QStandardItemModel * weight_zero_thirtysix_monthsModel = getDatasFromCsvFiles(WEIGHT_ZERO_THIRTYSIX_MONTHS);
    QStandardItemModel * height_zero_thirtysix_monthsModel = getDatasFromCsvFiles(HEIGHT_ZERO_THIRTYSIX_MONTHS);
    QStandardItemModel * weight_twentyfor_deuxhundredfortyone_monthModel = getDatasFromCsvFiles(WEIGHT_TWENTYFOR_DEUXHUNDREDANDFORTYONEMONTH);
    QStandardItemModel * height_twentyfor_deuxhundredfortyone_monthModel = getDatasFromCsvFiles(HEIGHT_TWENTYFOR_DEUXHUNDREDANDFORTYONEMONTH);
    //weight 0-36
    for (int row = 0; row < weight_zero_thirtysix_monthsModel->rowCount(); ++row)
    {
    	  QString sex = weight_zero_thirtysix_monthsModel->data(weight_zero_thirtysix_monthsModel->index(row,SD_SEX),Qt::DisplayRole).toString();
    	  if (sex.contains("2")||sex.contains("1"))
    	  {
    	  	  QList<QStandardItem*> listToRecord;
    	  	  for (int col = 0; col < SD_MaxParam; ++col)
    	  	  {
    	  	  	  QString data = weight_zero_thirtysix_monthsModel->data(weight_zero_thirtysix_monthsModel->index(row,col),Qt::DisplayRole).toString();
    	  	      QStandardItem* item = new QStandardItem(data);
    	  	      listToRecord << item;
    	  	      }
    	  	  if (sex.contains("2"))
    	  	  {
    	  	  	  m_weight_female_model->appendRow(listToRecord);
    	  	      }
    	  	  if (sex.contains("1"))
    	  	  {
    	  	  	  m_weight_male_model->appendRow(listToRecord);
    	  	      }    	  	  
    	      }
        }//for
    //weight 37-240
    for (int row = 0; row < weight_twentyfor_deuxhundredfortyone_monthModel->rowCount(); ++row)
    {
    	  QString sex = weight_twentyfor_deuxhundredfortyone_monthModel->data(weight_twentyfor_deuxhundredfortyone_monthModel->index(row,SD_SEX),Qt::DisplayRole).toString();
    	  QString age = weight_twentyfor_deuxhundredfortyone_monthModel->data(weight_twentyfor_deuxhundredfortyone_monthModel->index(row,SD_MONTH),Qt::DisplayRole).toString();
          if (sex.contains("2")||sex.contains("1"))
          {
          	  QList<QStandardItem*> listToRecord;
          	  if (age.toFloat()>36)
          	  {
          	  	  for (int col = 0; col < SD_MaxParam; ++col)
          	  	  {
          	  	  	  QString data = weight_twentyfor_deuxhundredfortyone_monthModel->data(weight_twentyfor_deuxhundredfortyone_monthModel->index(row,col),Qt::DisplayRole).toString();
          	  	          QStandardItem * item = new QStandardItem(data);
          	  	          listToRecord << item;
          	  	      }
    	  	          if (sex.contains("2"))
    	  	          {
    	  	  	      m_weight_female_model->appendRow(listToRecord);
    	  	              }
    	  	          if (sex.contains("1"))
    	  	          {
    	  	  	      m_weight_male_model->appendRow(listToRecord);
    	  	              }
          	      }
              }
        }//for
    //height 0-36
    for (int row = 0; row < height_zero_thirtysix_monthsModel->rowCount(); ++row)
    {
    	  QString sex = height_zero_thirtysix_monthsModel->data(height_zero_thirtysix_monthsModel->index(row,SD_SEX),Qt::DisplayRole).toString();
    	  if (sex.contains("2")||sex.contains("1"))
    	  {
    	  	  QList<QStandardItem*> listToRecord;
    	  	  for (int col = 0; col < SD_MaxParam; ++col)
    	  	  {
    	  	  	  QString data = height_zero_thirtysix_monthsModel->data(height_zero_thirtysix_monthsModel->index(row,col),Qt::DisplayRole).toString();
    	  	          QStandardItem* item = new QStandardItem(data);
    	  	          listToRecord << item;
    	  	      }
    	  	  if (sex.contains("2"))
    	  	  {
    	  	  	  m_height_female_model->appendRow(listToRecord);
    	  	      }
    	  	  if (sex.contains("1"))
    	  	  {
    	  	  	  m_height_male_model->appendRow(listToRecord);
    	  	      }
    	  	  
    	      }
        }//for
    //height 37-240
    for (int row = 0; row < height_twentyfor_deuxhundredfortyone_monthModel->rowCount(); ++row)
    {
    	  QString sex = height_twentyfor_deuxhundredfortyone_monthModel->data(height_twentyfor_deuxhundredfortyone_monthModel->index(row,SD_SEX),Qt::DisplayRole).toString();
    	  QString age = height_twentyfor_deuxhundredfortyone_monthModel->data(height_twentyfor_deuxhundredfortyone_monthModel->index(row,SD_MONTH),Qt::DisplayRole).toString();
          if (sex.contains("2")||sex.contains("1"))
          {
          	  QList<QStandardItem*> listToRecord;
          	  if (age.toFloat()>36)
          	  {
          	  	  for (int col = 0; col < SD_MaxParam; ++col)
          	  	  {
          	  	  	  QString data = height_twentyfor_deuxhundredfortyone_monthModel->data(height_twentyfor_deuxhundredfortyone_monthModel->index(row,col),Qt::DisplayRole).toString();
          	  	          QStandardItem * item = new QStandardItem(data);
          	  	          listToRecord << item;
          	  	      }
    	  	         if (sex.contains("2"))
    	  	         {
    	  	  	      m_height_female_model->appendRow(listToRecord);
    	  	             }
    	  	         if (sex.contains("1"))
    	  	         {
    	  	  	      m_height_male_model->appendRow(listToRecord);
    	  	             }
          	      }
              }
        }//for
    //bmi 0-240
    //calc and get bmi
    //female
    for (int r = 0; r < m_weight_female_model->rowCount() ;++r)
    {
    	  QList<QStandardItem*> listToRecord;
    	  for (int col = 0;  col < SD_MaxParam; ++ col)
    	  {
    	  	  QString weightData = m_weight_female_model->data(m_weight_female_model->index(r,col),Qt::DisplayRole).toString();
    	  	  QString heightData = m_height_female_model->data(m_height_female_model->index(r,col),Qt::DisplayRole).toString();
    	  	  QStandardItem* item = new QStandardItem;
    	  	  if (col < SD_MONTH+1)
    	  	  {
    	  	  	 item->setText(weightData); 
    	  	      }
    	  	  else
    	  	  {
    	  	  	float weight = weightData.toFloat();
    	  	  	float height = heightData.toFloat();
    	  	  	float bmi = calcBmi(weight,height);
    	  	  	item->setText(QString::number(bmi));
    	  	      }
    	  	  listToRecord << item;
    	      }//for
        m_bmi_female_model->appendRow(listToRecord);
        }//for
    //rest of life of female
    int maxLifeInDays = 43800;
    int maxHalfMonths = maxLifeInDays/15;
    int lastRow = m_bmi_female_model->rowCount()-1;
    double halfMonthFemale = 240.5;
    for (int i = 241; i < maxHalfMonths; ++i)
    {
    	  QList<QStandardItem*> listToRecord;
    	  for (int col = 0;  col < SD_MaxParam; ++ col)
    	  {    	  
    	  	  QString weightData = m_weight_female_model->data(m_weight_female_model->index(lastRow,col),Qt::DisplayRole).toString();
    	  	  QString heightData = m_height_female_model->data(m_height_female_model->index(lastRow,col),Qt::DisplayRole).toString();
    	  	  QStandardItem* item = new QStandardItem;    
    	  	  if (col < SD_MONTH)
    	  	  {
    	  	  	 item->setText(weightData); 
    	  	      }
    	  	  else if (col == SD_MONTH)
    	  	  {
    	  	  	  halfMonthFemale = halfMonthFemale + 0.50;
    	  	  	  item->setText(QString::number(halfMonthFemale)); 
    	  	      }
    	  	  else
    	  	  {
    	  	  	float weight = weightData.toFloat();
    	  	  	float height = heightData.toFloat();
    	  	  	float bmi = calcBmi(weight,height);
    	  	  	item->setText(QString::number(bmi));
    	  	      }
    	  	  listToRecord << item;	      
    	      }
        m_bmi_female_model->appendRow(listToRecord);
        }//for
    //male
    for (int r = 0; r < m_weight_male_model->rowCount() ;++r)
    {
    	  QList<QStandardItem*> listToRecord;
    	  for (int col = 0;  col < SD_MaxParam; ++ col)
    	  {
    	  	  QString weightData = m_weight_male_model->data(m_weight_male_model->index(r,col),Qt::DisplayRole).toString();
    	  	  QString heightData = m_height_male_model->data(m_height_male_model->index(r,col),Qt::DisplayRole).toString();
    	  	  QStandardItem* item = new QStandardItem;
    	  	  if (col < SD_MONTH+1)
    	  	  {
    	  	  	 item->setText(weightData);  	  	  	 
    	  	      }
    	  	  else
    	  	  {
    	  	  	float weight = weightData.toFloat();
    	  	  	float height = heightData.toFloat();
    	  	  	float bmi = calcBmi(weight,height);
    	  	  	item->setText(QString::number(bmi));
    	  	      }
    	  	  listToRecord << item;
    	      }//for
        m_bmi_male_model->appendRow(listToRecord);
        }//for 
    //rest of life of male
    lastRow = m_bmi_male_model->rowCount()-1;
    double halfMonth = 240.5;
    for (int i = 241; i < maxHalfMonths; ++i)
    {
    	  QList<QStandardItem*> listToRecord;
    	  for (int col = 0;  col < SD_MaxParam; ++ col)
    	  {    	  
    	  	  QString weightData = m_weight_male_model->data(m_weight_male_model->index(lastRow,col),Qt::DisplayRole).toString();
    	  	  QString heightData = m_height_male_model->data(m_height_male_model->index(lastRow,col),Qt::DisplayRole).toString();
    	  	  QStandardItem* item = new QStandardItem;      	  	  
    	  	  if (col < SD_MONTH)
    	  	  {
    	  	  	 item->setText(weightData); 
    	  	  	 }
    	  	  else if (col == SD_MONTH)
    	  	  {
    	  	  	  halfMonth = halfMonth + 0.50;
    	  	  	  item->setText(QString::number(halfMonth)); 
    	  	  	  }
    	  	  else
    	  	  {
    	  	  	float weight = weightData.toFloat();
    	  	  	float height = heightData.toFloat();
    	  	  	float bmi = calcBmi(weight,height);
    	  	  	item->setText(QString::number(bmi));
    	  	    }
    	  	  listToRecord << item;	      
    	      }
    	  m_bmi_male_model->appendRow(listToRecord);
        }//for   
        
    qDebug() << __FILE__ << QString::number(__LINE__) << " m_bmi_male_model count =" << QString::number(m_bmi_male_model->rowCount()) ;
}

QStringList BmiManager::getListOfPointsInDays()
{
    QStringList list;
    int maxLifeInDays = 43800;
    for (int i = 0; i < maxLifeInDays; ++i)
    {
    	  list << QString::number(i);
        }
    return list;
}

float BmiManager::calcBmi(float weight,float height)
{
    if (weight == 0.0000 || height == 0.0000)
    {
    	  return 0.0000;
        }
    float heightInMeter = height/100;
    return weight/heightInMeter/heightInMeter;
}

QStandardItemModel * BmiManager::getWeightFemale()
{
    return m_weight_female_model;
}

QStandardItemModel * BmiManager::getHeightFemale()
{
    return m_height_female_model;
}

QStandardItemModel * BmiManager::getBmiFemale()
{
    return m_bmi_female_model;
}

QStandardItemModel * BmiManager::getWeightMale()
{
    return m_weight_male_model;
}

QStandardItemModel * BmiManager::getHeightMale()
{
    return m_height_male_model;
}

QStandardItemModel * BmiManager::getBmiMale()
{
    return m_bmi_male_model;
}

float BmiManager::calcDateInMonthsSinceBirthday(QDate date,QDate birthday)
{
    int years = date.year() - birthday.year();
    int remainedMonths = date.month() - birthday.month();
    return float(years*12 + remainedMonths);
}

float BmiManager::calcBmiFromWeightAndHeight(float weight,float height)
{
    float heightInMeter = 0;
    if (height > 10.0)
    {
          heightInMeter = height/100;
        }
    else
    {
        heightInMeter = height;
        }
    return weight/(heightInMeter*heightInMeter);
}

bool BmiManager::firsttimeMessage()
{
    QString message = tr("Vous lancez le programme pour la première fois.\n"
                         "Veuillez paramétrer ressources/config.ini avec vos données de connexion\n"
                         "et le programme appelant :\n"
                         "medintux si vos données sont stockées dans l'observation \n(poids:\ntaille:)\n"
                         "medintux-inside si vos données sont stockées dans le terrain.");
    QMessageBox mess;
    mess.setText(message);
    mess.setStandardButtons(QMessageBox::Ok|QMessageBox::No);   
    mess.setDefaultButton(QMessageBox::Ok);
    int messresult = mess.exec();
    if (messresult==QMessageBox::Ok)
    {
          return true;
        }
    return false;
}

void BmiManager::configRecordAllRight()
{
    QMessageBox::information(0,tr("Information"),tr("La configuration a été enregistrée."),QMessageBox::Ok);
}

void BmiManager::exitOfApplicationMessage()
{
    QMessageBox::information(0,tr("Information"),tr("Le programme va fermer."),QMessageBox::Ok);
}

void BmiManager::setAllLifeBmiAccordMonths()
{
    QFile allLifeMaleAndFemaleBmi("alllifebmi.csv");
    if (allLifeMaleAndFemaleBmi.exists())
    {
          qWarning() << __FILE__ << QString::number(__LINE__) << "allLifeMaleAndFemaleBmi.csv already exists" ;
          return;
        }
    if (!allLifeMaleAndFemaleBmi.open(QIODevice::WriteOnly))
    {
          qWarning() << __FILE__ << QString::number(__LINE__) << "unable to open allLifeMaleAndFemaleBmi.csv" ;
        }
    QTextStream bmiStream(&allLifeMaleAndFemaleBmi);
    for ( int row = 0; row < m_bmi_female_model->rowCount(); ++row)
    {
          for (int col = 0;  col < m_bmi_female_model->columnCount(); ++col)
          {
              bmiStream << m_bmi_female_model->data(m_bmi_female_model-> index(row,col),Qt::DisplayRole).toString()+";";              
              }
           bmiStream << "\n";
          }
    for ( int row = 0; row < m_bmi_male_model->rowCount(); ++row)
    {
        for ( int col = 0; col < m_bmi_male_model->columnCount(); ++ col)
        {
              bmiStream << m_bmi_male_model->data(m_bmi_male_model-> index(row,col),Qt::DisplayRole).toString()+";";
            }
         bmiStream << "\n";
        }    
}

